package UI;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JViewport;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import Logical.Card;
import Logical.CardsMover;
import MulThread.TimerDelegate;
import User.Gamer;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;



public class MainWindow implements TimerDelegate {

	private JFrame frame;
	private JPanel childPanel;
	private JMenu mnNewMenu;
	private FlowLayout layout;
	private JMenuBar menuBar ;
	public static int  WINTag = 0;
	private JTextField textField;
	private ArrayList<Card> cards ;
	
	//game statue
	private int REDADY = 0;
	private int START = 1;
	private int OVER = -1;
	
	private int STATUE = OVER;
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainWindow window = new MainWindow();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public MainWindow() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		
		
		
		childPanel = new JPanel();
		
		
		frame.setBounds(500, 300, 300,300);
		Card card= new Card(0);
		childPanel.add(card.preferenceSetting());
//		frame.setSize(new Dimension(1000,2000));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		//timer ..
		textField = new JTextField();
		textField.setEditable(false);
		
		
		
		
		textField.setColumns(2);
		frame.getContentPane().add(childPanel);
		//setting popMenu
		
		layout = new FlowLayout();
		frame.getContentPane().setLayout(layout);
		
		
		frame.setResizable(true);
		
		//menu setting 
		menuBar = new JMenuBar();
		frame.setJMenuBar(menuBar);
		
		mnNewMenu = new JMenu("menu");
		JMenuItem newGameButton = new JMenuItem("New Game(4X4)");
		JMenuItem lookrankButton = new JMenuItem("Rank");
		JMenuItem exitGameButton = new JMenuItem("Exit");
		exitGameButton.addActionListener(new ExitButtonListener());
		lookrankButton.addActionListener(new RankLook());
		newGameButton.addActionListener(new NewGameListener());
		mnNewMenu.add(newGameButton);
		mnNewMenu.add(lookrankButton);
		mnNewMenu.add(exitGameButton);
		
		menuBar.add(mnNewMenu);
		//mue setting end;
		
		//card 

//		CardGenerater(4);
//		frame.setSize(new Dimension(2*230,2*310));
		//card end
		
	}
	
	private void CardInitilization(int size,CardsMover movers) {
		// TODO Auto-generated method stub
		ArrayList<Integer> cardIDs =  movers.RandomSort(size);
		cards = movers.getCards();
		for (int i =0 ; i<cards.size();i++){
			cards.get(i).setCardID(cardIDs.get(i));
//			cards.get(i).DisplayID();
			childPanel.setSize(size *105,size*205);
			childPanel.add(cards.get(i).preferenceSetting());
			
		}
		STATUE = REDADY;
		for(Card card : cards){
			card.displayFront();
		}
		Timer iniTimer = new Timer(this,10000);
		Thread iniThread = new Thread(iniTimer);
		iniThread.start();
		frame.pack();
		
	}

	public void CardGenerater(final int size,final Gamer gamer){
		childPanel.setLayout(new GridLayout(size,size));
		System.out.println("Ready");
		if (frame != null){
			frame.setSize(new Dimension(120*size,210*size));
			GridLayout gridLayout = new GridLayout(size,size);
			frame.getContentPane().setLayout(gridLayout);
			CardsMover cardsMover = new CardsMover(size);
			
			CardInitilization(size, cardsMover);
			final long startT = System.currentTimeMillis();
			
			final Thread winThread  = new Thread(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					while (true){
						System.out.println("wintag :"+String.valueOf(WINTag));
						if (WINTag ==1){
							gamer.END();
							break;
						}
						if (System.currentTimeMillis()- startT >60000){
							break;
						}
						try {
							Thread.sleep(500);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}
					menuBar.remove(textField);
					if (System.currentTimeMillis()- startT > 60000){
						Lose();
					}else{
						Win();
					}
				}

				
			});
			Thread listenerThread = new Thread(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					while(true){
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						System.out.println("Start ?");
						if (STATUE == START){
							System.out.println("Start");
							break;
						}
					}
					winThread.start();
				}
			});
			listenerThread.start();
			
		}
		
	}
	private void Lose() {
		// TODO Auto-generated method stub
		childPanel.remove(1);
		JOptionPane.showConfirmDialog(null, "You lose");
	}
	
	public static void setWinTag(int tag){
		WINTag = tag;
	}
	
	//exit 
	class ExitButtonListener implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			
			frame.dispose();
		}
		
	}
	
	
	//new game
	class NewGameListener implements ActionListener{


		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			
			childPanel.removeAll();
			
			//com area
			JButton primaryRankButton = new JButton("Primary");
			JButton heighRankButton = new JButton("Height");
			JPanel thisJPanel  =new JPanel();
			thisJPanel.add(primaryRankButton);
			thisJPanel.add(heighRankButton);
			
			Object[] chioced =  {"Primary","Height"};
			Object selected = JOptionPane.showInputDialog(
					null,
					"Choice one",
					"Input",
					JOptionPane.INFORMATION_MESSAGE,
					null,
					chioced,
					chioced[0]
					);
			System.out.println(selected);
			if (selected != null){
				if (selected.equals("Primary")){
					StartGame(2);
				}else if (selected.equals("Height")){
					StartGame(4);
				}
			}

			frame.pack();
			
		}
	}
	private void StartGame(int size){
		String name = JOptionPane.showInputDialog("Input gamer name:");
		Gamer gamer = new Gamer(name);
		gamer.StartGame();
		NewGame(size, gamer);
	}
	private void NewGame(int size,Gamer gamer){
		
		WINTag = 0;
		menuBar.add(textField);
		CardGenerater(size,gamer);
		Timer timecounter = new Timer(this, 60000);
		Thread timerThread = new Thread(timecounter);
		timerThread.start();
	}
	
	
	public void Win(){
		CardsMoverAnimation(childPanel);
		System.out.println("move...");
		
		setWinTag(0);
		JOptionPane.showConfirmDialog(null, "You Win");

	}
	

	
	public  void CardsMoverAnimation(JPanel panel){
		System.out.println("starting ... animation");
		for(int i =0 ;i<panel.getComponentCount();i++){
			JPanel panelInJPanel= (JPanel)panel.getComponent(i);
			Card card = (Card) panelInJPanel.getComponent(0);
			CardAnimation animation = new CardAnimation(card, 0, 10000);
			Thread animationThread = new Thread(animation);
			animationThread.start();
		}
		Thread finalThread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				childPanel.removeAll();
				System.out.println("removeing...");
				Card card= new Card(0);
				childPanel.add(card.preferenceSetting());
				childPanel.setSize(200,200);
				frame.setSize(250, 350);
				System.out.println("ok");
				frame.pack();
			}
		});
		finalThread.start();
	}
	
	class CardAnimation implements Runnable{
		private Card card;
		private int moverHeight =0;
		private int moverLeft=0;
		public CardAnimation(Card card,int left,int heigh) {
			// TODO Auto-generated constructor stub
			this.card = card;
			this.moverHeight = heigh;
			this.moverLeft = left;
		}
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			int moverH =this.moverHeight/10000;
			int moverL = this.moverLeft/10000;
			int count  =0;
			while (count <10000){
				card.setLocation(card.getX()+ moverL, card.getY()+ moverH);
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				count ++;
			}
		}
		
	}
	
	class RankLook implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent arg0) {
			// TODO Auto-generated method stub
			
			
			childPanel.removeAll();
			JScrollPane scrollPane = new JScrollPane();
			scrollPane.setPreferredSize(new Dimension(300,500));
			JViewport viewport = new JViewport();
			scrollPane.setViewport(viewport);
			
			JPanel centerPanel = new JPanel();
			viewport.add(centerPanel); 
			centerPanel.setName("rank");
			centerPanel.setLayout(new GridLayout(80,2));
			centerPanel.setBounds(frame.getWidth()/2, frame.getHeight()/2, 100, 100);
			
			childPanel.add(scrollPane);
			File file = new File("res/save/rank.rk");
		    BufferedReader reader = null;
			try {
				reader = new BufferedReader( new FileReader(file));
				String resultString ;
				while ((resultString = reader.readLine() )!= null){
					AddLine(centerPanel, resultString);
				}
				reader.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally{
				try {
					reader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			frame.pack();
		}
		
		private void AddLine(JPanel panel,String line){
			JTextField textLine = new JTextField(line);
			textLine.setEditable(false);
			panel.add(textLine);			
			
		}
	}
	
	
	class Timer implements Runnable{
		public   boolean END = false;
		public TimerDelegate timer ;
		public long timeDelay;
		public Timer(TimerDelegate timerDelegate,long timedelay) {
			this.timer = timerDelegate;
			this.timeDelay = timedelay;
			// TODO Auto-generated constructor stub
		}
		public synchronized void sendInfo(long i){
			timer.recived(i);
		}
		public synchronized void sendLessInfo(){
			timer.Init();
		}
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (timeDelay > 10000){
				while (timeDelay >0){
					try {
						Thread.sleep(1000);
						timeDelay -= 1000;
						sendInfo(timeDelay);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
			}else{
				while (timeDelay >0){
					try {
						Thread.sleep(1000);
						timeDelay -= 1000;
						
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
				sendLessInfo();
			}
		}
		
	}
	@Override
	public void recived(long i) {
		// TODO Auto-generated method stub
		setTimer(i);
	}
	public void setTimer(long i){
		textField.setText(String.valueOf(i/1000));
	}

	@Override
	public void End() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void Init() {
		// TODO Auto-generated method stub
		for(Card card:cards){
			card.displayBack();
		}
		STATUE = START;
	}
}
